package banco;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Date;
import banco.guiFuncionario;

public class BancoDados {
	public ArrayList<Funcionario> funcionarios;
	public ArrayList<Cliente> clientes;
	public ArrayList<Agencia> agencias;
	public ArrayList<ContaCorrente> contas;	
	public ArrayList<Deposito> depositosAguardandoVerificacao;	
	
	public BancoDados() {
		this.funcionarios = new ArrayList<Funcionario>();
		this.clientes = new ArrayList<Cliente>();
		this.agencias = new ArrayList<Agencia>();
		this.contas = new ArrayList<ContaCorrente>();
		this.depositosAguardandoVerificacao = new ArrayList<Deposito>();		
	}
		
	
	public static void main(String[] args) throws ParseException {
		BancoDados dadosSistema = new BancoDados();
		Agencia percorreListaAgencia = new Agencia();
		Agencia agenciaEncontrada = new Agencia(); 
		guiFuncionario opcoesGUIFunc = new guiFuncionario();
		guiCliente opcoesGUICliente = new guiCliente();
		ContaCorrente novaConta = new ContaCorrente();
		boolean desejaSair = false;
		boolean semErros = false;
		Funcionario funcionarioLogado = new Funcionario();
		Cliente clienteLogado = new Cliente();
		Scanner controleInput = new Scanner(System.in);
		int controleOpcao = 0;
		int controleOperacao = 0;
		int nroAgencia = 0;
		int nroConta = 0;
		float valor = 0;
		
		Date data = new Date();
		Agencia agenciaMatriz = new Agencia(0, "matriz");
		dadosSistema.agencias.add(agenciaMatriz);
		
		Cliente cliente1 = new Cliente();
		dadosSistema.clientes.add(cliente1);
		Cliente cliente2 = new Cliente("Jorge", "Silva", 999, data);
		dadosSistema.clientes.add(cliente2);
		Cliente cliente4 = new Cliente("Jorge", "Silva", 777, data);
		dadosSistema.clientes.add(cliente4);
		Agencia agencia1 = new Agencia(1, "Centro");
		dadosSistema.agencias.add(agencia1);
		Funcionario funcionario1 = new Funcionario();
		dadosSistema.funcionarios.add(funcionario1);
		Funcionario funcionario2 = new Funcionario("Carlos", "Souza", "20/08/1981", "csouza", "123");
		dadosSistema.funcionarios.add(funcionario2);
						
		while(!desejaSair) {
			System.out.println("Bem-vindo ao sistema. Determine seu acesso:\n");
			System.out.println("1 - Agencia\n2 - Caixa Eletronico\n3 - Sair");
			controleOpcao = controleInput.nextInt();
			
			agenciaEncontrada = null;
			semErros = false;
			
			switch (controleOpcao) {
				case 1:
					System.out.println("Por favor, informe o n�mero de sua ag�ncia:");
					nroAgencia = controleInput.nextInt();
					for(int i = 0; i<dadosSistema.agencias.size(); i++)
					{
						percorreListaAgencia = dadosSistema.agencias.get(i);
						
						if(percorreListaAgencia.numero == nroAgencia) {
								agenciaEncontrada = percorreListaAgencia;
							}
					}
					if(agenciaEncontrada!=null) {
						if(agenciaEncontrada.nome!=null) {
							System.out.println("Por favor, digite seu usuario:");
							String user = controleInput.next();		
							System.out.println("Ol� " + user + ", por favor, digite sua senha:");
							String senha = controleInput.next();
							funcionarioLogado = opcoesGUIFunc.login(user, senha, dadosSistema);
						}
					}
					else
						System.out.println("Ag�ncia n�o existente.");
					break;
				case 2:
					System.out.println("Por favor, digite seu n�mero de conta:");
					nroConta = controleInput.nextInt();
					System.out.println("Por favor, digite sua senha:");
					String senhaCliente = controleInput.next();
					clienteLogado = opcoesGUICliente.login(nroConta, senhaCliente, dadosSistema);
					break;
				case 3:
					desejaSair = true;
					break;
				default:
					System.out.println("Resposta inconsistente, por favor, tente de novo.\n");
					break;
			}
			if(clienteLogado.conta != null) {
				while(clienteLogado.conta != null) {
					System.out.println("Escolha sua opera��o:\n");
					System.out.println("1 - Saldo\n2 - Extrato\n3 - Dep�sito\n4 - Saque\n5 - Transfer�ncia\n6 - Pagamento\n7 - Logout\n");
					controleOperacao = controleInput.nextInt();
					
					int envelope = 0;
					switch (controleOperacao) {						
					case 1:
						semErros = opcoesGUICliente.imprimeSaldo(nroConta, dadosSistema);
						if(!semErros)
							System.out.println("Conta inexistente.\n");
						break;
					case 2:
						semErros = opcoesGUICliente.imprimeExtrato(nroConta, dadosSistema);
						clienteLogado = opcoesGUICliente.logout(dadosSistema);
						if(!semErros)
							System.out.println("Conta inexistente.\n");
						break;
					case 3:
						System.out.println("Informe o n�mero de sua ag�ncia:\n");
						nroAgencia = controleInput.nextInt();
						System.out.println("Informe o valor de dep�sito:\n");
						valor = controleInput.nextFloat();
						System.out.println("Informe o n�mero do envelope:\n");
						envelope = controleInput.nextInt();
						semErros = opcoesGUICliente.fazDepositoComVerificacao(nroConta, nroAgencia, valor, envelope, dadosSistema);
						if(!semErros)
							System.out.println("Dados inconsistentes.\n");
						break;
					case 4:
						System.out.println("Informe o n�mero de sua ag�ncia:\n");
						nroAgencia = controleInput.nextInt();
						System.out.println("Informe o valor a ser sacado:\n");
						valor = controleInput.nextFloat();
						semErros = opcoesGUICliente.fazSaque(nroAgencia, nroConta, valor, dadosSistema);
						if(!semErros)
							System.out.println("Conta inexistente ou Saldo insuficiente para efetuar a operação.\n");
						break;
					case 5:
						System.out.println("Informe o n�mero de sua ag�ncia:\n");
						nroAgencia = controleInput.nextInt();
						System.out.println("Informe o numero da ag�ncia de destino:\n");
						int nroAgenciaDestino = controleInput.nextInt();
						System.out.println("Informe o numero da conta de destino:\n");
						int nroContaDestino = controleInput.nextInt();
						System.out.println("Informe o valor a ser transferido:\n");
						valor = controleInput.nextFloat();
						semErros = opcoesGUICliente.fazTransferencia(nroAgencia, nroAgenciaDestino, nroConta, nroContaDestino, valor, dadosSistema);
						if(!semErros)
							System.out.println("Dados inconsistentes ou Saldo insuficiente para efetuar a operação.\n");
						break;
					case 6:
						System.out.println("Informe o n�mero de sua ag�ncia:\n");
						nroAgencia = controleInput.nextInt();
						System.out.println("Informe o numero da ag�ncia de destino:\n");
						int nroAgenciaDestinoPagamento = controleInput.nextInt();
						System.out.println("Informe o numero da conta de destino:\n");
						int nroContaDestinoPagamento = controleInput.nextInt();
						System.out.println("Informe a data de vencimento do pagamento: (usando o formato ddMMyyyy)\n");
						String dataVencimentoPagamento = controleInput.next();						
						System.out.println("Informe o valor do pagamento a ser efetuado:\n");
						valor = controleInput.nextFloat();
						System.out.println("Informe o valor da multa a ser aplicada após a data de vencimento:\n");
						float multaPagamento = controleInput.nextFloat();						
						semErros = opcoesGUICliente.efetuaPagamento(nroAgencia, nroAgenciaDestinoPagamento, nroConta, nroContaDestinoPagamento, dataVencimentoPagamento, valor, multaPagamento, dadosSistema);
						if(!semErros)
							System.out.println("Dados inconsistentes ou Saldo insuficiente para efetuar a operação.\n");
						break;					
					case 7:
						clienteLogado = opcoesGUICliente.logout(dadosSistema);
						break;
					default:
						System.out.println("Opera��o incorreta.\n");
						break;
					}
				}
			} else if (funcionarioLogado.user != null){
				while(funcionarioLogado.user!=null) {
					System.out.println("Escolha sua opera��o:\n");
					System.out.println("1 - Criar Nova Conta\n2 - Saldo\n3 - Extrato\n4 - Dep�sito\n5 - Saque\n6 - Transfer�ncia\n7 - Pagamento\n8 - Verifica Depósitos\n9 - Logout\n");
					controleInput.nextLine();
					controleOperacao = controleInput.nextInt();
					
					if((controleOperacao-1)>0) {
						if(controleOperacao!=9 && controleOperacao != 8) {
							System.out.println("Informe o numero da conta de origem:\n");
							nroConta = controleInput.nextInt();
						}
						
						int envelope = 0;
						switch (controleOperacao) {						
							case 2:
								semErros = opcoesGUIFunc.imprimeSaldo(nroConta, dadosSistema);
								if(!semErros)
									System.out.println("Conta inexistente.\n");
								break;
							case 3:
								semErros = opcoesGUIFunc.imprimeExtrato(nroConta, dadosSistema);
								if(!semErros)
									System.out.println("Conta inexistente.\n");
								break;
							case 4:
								System.out.println("Informe o valor de dep�sito:\n");
								valor = controleInput.nextFloat();
								System.out.println("Informe o n�mero do envelope:\n");
								envelope = controleInput.nextInt();
								semErros = opcoesGUIFunc.fazDeposito(nroConta, nroAgencia, valor, envelope, dadosSistema);
								if(!semErros)
									System.out.println("Dados inconsistentes.\n");
								break;
							case 5:
								System.out.println("Informe o valor a ser sacado:\n");
								valor = controleInput.nextFloat();
								semErros = opcoesGUIFunc.fazSaque(nroAgencia, nroConta, valor, dadosSistema);
								if(!semErros)
									System.out.println("Conta inexistente.\n");
								break;
							case 6:
								System.out.println("Informe o numero da ag�ncia de destino:\n");
								int nroAgenciaDestino = controleInput.nextInt();
								System.out.println("Informe o numero da conta de destino:\n");
								int nroContaDestino = controleInput.nextInt();
								System.out.println("Informe o valor a ser transferido:\n");
								valor = controleInput.nextFloat();
								semErros = opcoesGUIFunc.fazTransferencia(nroAgencia, nroAgenciaDestino, nroConta, nroContaDestino, valor, dadosSistema);
								if(!semErros)
									System.out.println("Dados inconsistentes.\n");
								break;
							case 7:
								System.out.println("Informe o numero da ag�ncia de destino:\n");
								int nroAgenciaDestinoPagamento = controleInput.nextInt();
								System.out.println("Informe o numero da conta de destino:\n");
								int nroContaDestinoPagamento = controleInput.nextInt();
								System.out.println("Informe a data de vencimento do pagamento: (usando o formato ddMMyyyy)\n");
								String dataVencimentoPagamento = controleInput.next();						
								System.out.println("Informe o valor do pagamento a ser efetuado:\n");
								valor = controleInput.nextFloat();
								System.out.println("Informe o valor da multa a ser aplicada após a data de vencimento:\n");
								float multaPagamento = controleInput.nextFloat();						
								semErros = opcoesGUIFunc.efetuaPagamento(nroAgencia, nroAgenciaDestinoPagamento, nroConta, nroContaDestinoPagamento, dataVencimentoPagamento, valor, multaPagamento, dadosSistema);
								if(!semErros)
									System.out.println("Dados inconsistentes ou Saldo insuficiente para efetuar a operação.\n");
								break;
							case 8:
								System.out.println("Escolha o Depósito que deseja verificar:\n\n");
								
								// Imprime depósitos na tela
								Deposito iterDepositos;
								for (int i = 0; i < dadosSistema.depositosAguardandoVerificacao.size(); i++) {
									iterDepositos = dadosSistema.depositosAguardandoVerificacao.get(i);
									System.out.println("(" + i+1 + ")" + "\nConta Destino: " + iterDepositos.contaDestino + "\nValor: " + iterDepositos.valor + "\n");
								}
								
								// Efetua o depósito escolhido
								int nroDepositoVerificar = controleInput.nextInt();		
								Deposito depositoVerificar = dadosSistema.depositosAguardandoVerificacao.get(nroDepositoVerificar-1);
								semErros = opcoesGUIFunc.fazDeposito(depositoVerificar.contaDestino, depositoVerificar.agenciaDestino, depositoVerificar.valor, depositoVerificar.envelope, dadosSistema);
								if (!semErros){
									System.out.println("Dados inconsistentes.\n");										
								}
								else {
									// Remove depósito da lista de verificação
									dadosSistema.depositosAguardandoVerificacao.remove(nroDepositoVerificar-1);
									System.out.println("Depósito verificado com sucesso!\n");	
								}
								break;								
							case 9:
								funcionarioLogado = opcoesGUIFunc.logout(dadosSistema);
								break;								
							default:
								System.out.println("Opera��o incorreta.\n");
								break;
						}
					}
					else  if (controleOperacao==1) {
						System.out.println("Informe o cpf do novo dono da conta:\n");
						double cpf = controleInput.nextInt();
						System.out.println("Informe o valor inicial da conta:\n");
						valor = controleInput.nextFloat();
						novaConta = opcoesGUIFunc.criaConta(nroAgencia, cpf, valor, dadosSistema);
						if(novaConta.numero == -1)
							System.out.println("Dados inconsistentes.\n");
					}
				}
			} else {
				System.out.println("Cadastro n�o encontrado.\n");
			}
		}
		controleInput.close();
	}
}
